package com.qf.smsplatfrom.controller.advice;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.smsplatfrom.annotations.IgnoreLog;
import com.qf.smsplatfrom.annotations.LogOperationAnno;
import com.qf.smsplatfrom.mapper.TLogbeanMapper;
import com.qf.smsplatfrom.pojo.MyAuthUser;
import com.qf.smsplatfrom.pojo.TLogbean;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
@Aspect
public class LogAdvice {


    private TLogbeanMapper tLogbeanMapper;

    @Autowired
    public void settLogbeanMapper(TLogbeanMapper tLogbeanMapper) {
        this.tLogbeanMapper = tLogbeanMapper;
    }

    private ObjectMapper objectMapper;

    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    //public void com.qianfeng.controller.xxxcontroller.addUser(String username) throw xxxEx
    //修饰符 返回值 包.类.方法名(参数) 异常
    @Pointcut("execution(* com.qf.smsplatfrom.controller.*Controller.*(..))")
    public void pc() {

    }


    @Around("pc()")
    public Object processLog(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Object target = joinPoint.getTarget();//获取到当前方法所在的类对象
        Method method = signature.getMethod();//当前正在执行的方法
        Object[] args = joinPoint.getArgs();//当前方法需要传递的参数
        Object proceed = joinPoint.proceed();//方形获取原始结果

        //获取自己新建的注释标识为
        IgnoreLog annotation = method.getAnnotation(IgnoreLog.class);
        if (annotation != null) {
            return proceed;
        }
        //创建实体类对象
        TLogbean tLogbean = new TLogbean();
        //此刻的标识为是为了获得他上边的所有信息,获取当前类上的自定义注解，为了知道当前类具体干什莫操作
        LogOperationAnno logOperationAnno = method.getAnnotation(LogOperationAnno.class);
        //判断标识为是否为空，如果不为空，则进行存入
        if (logOperationAnno != null) {
            String oper = logOperationAnno.value();
            tLogbean.setOper(oper);
        }
        //获取到当前操作的时间
        tLogbean.setAccessDate(new Date());
        //获取到当前登录的对象
        MyAuthUser principal = (MyAuthUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //判断登陆的对象是否是空
        if (principal != null) {
            tLogbean.setType(principal.getType());
            tLogbean.setUserId(principal.getId());
        }
        //获取方法上传递的操作信息
        String[] parameterNames = signature.getParameterNames();//获取到方法上的传递的参数名
        //判断是否是为空
        if (parameterNames != null) {
            Map map = new HashMap();//保存每个参数的map集合
            for (int i = 0; i < parameterNames.length; i++) {//遍历输出
                String parameterName = parameterNames[i];//拿到所有方法的参数名
                Object arg = args[i];//拿到所有方法的参数列表
                map.put(parameterName, arg);//存入到集合中
            }
            tLogbean.setParams(objectMapper.writeValueAsString(map));//将东西转换成json对象存入到对象中
        }
        //将返回结果保存
        tLogbean.setResult(objectMapper.writeValueAsString(proceed));
        //调用方法存入数据库
        tLogbeanMapper.insertTLogBean(tLogbean);
        return proceed;
    }


}
